﻿#include "cdbbaseoper.h"
#include <QStringList>
#include <QSqlError>
#include <QSqlRecord>
#include <QDateTime>
#include <QMutex>
#include "cdbmysqloper.h"
#include "cdbopengaussoper.h"
#include "cdboracleoper.h"
#include "cdbsqlserveroper.h"
#include "cdbaccessoper.h"
#include "cdbsqliteoper.h"
#include "cdbodbcoper.h"
#include "cdbdmoper.h"
#include "cdbtableinfomgr.h"
#include <QDebug>
#include <QString>

#define DB_A2T QString
const int TRY_LOCK_TIME = 10;   //尝试加锁时间，单位ms
const QString MYSQL_DRIVER_NAME         = "Mysql";          //Mysql
const QString ORACLE_DRIVER_NAME        = "Oracle";         //Oracle
const QString ODBC_DRIVER_NAME          = "ODBC";           //ODBC
const QString ACCESS_DRIVER_NAME        = "Access";         //ACCESS
const QString POSTGRE_DRIVER_NAME       = "PostgreSql";     //PostgreSQL
const QString OPENGAUSS_DRIVER_NAME     = "openGauss";      //高斯
const QString SQLSERVER_DRIVER_NAME     = "SqlServer";      //sqlserver
const QString SQLITE_DRIVER_NAME        = "SQLite";         //sqlite
const QString DAMENG_DRIVER_NAME        = "DaMeng";         //达梦

CDbTableInfoMgr *getTableInfoMgr(CDbTableDataInfo *pInfo)
{
    if(nullptr == pInfo) return nullptr;
    CDbTableInfoMgr *mgr = dynamic_cast<CDbTableInfoMgr*>(pInfo);
    return mgr;
}

CDbBaseOper::CDbBaseOper(const QString &sConnectInfo)
    : m_pLog(nullptr)
    , m_pMutex(new QMutex())
{
    QStringList sListStr;
    sListStr = sConnectInfo.split(";");
    if (sListStr.size() >= 5)
    {
        m_dbCfg.sName = sListStr[0];
        m_dbCfg.nPort = sListStr[1].toInt();
        m_dbCfg.sIP = sListStr[2];
        m_dbCfg.sUserName = sListStr[3];
        m_dbCfg.sPassWord = sListStr[4];
    }
}

CDbBaseOper::CDbBaseOper(const CDataBaseConfig &cDbCfg)
    : m_dbCfg(cDbCfg)
    , m_pLog(nullptr)
    , m_pMutex(new QMutex())
{
}

CDbBaseOper::~CDbBaseOper()
{
    m_db.close();
    if(nullptr != m_pMutex)
    {
//        m_pMutex->lock();
        delete m_pMutex;
        m_pMutex = nullptr;
    }
}

CDbBaseOper *CDbBaseOper::createCDbSqlOper(const int &nDbType, const QString &sConnectInfo,
                                           const QString &sConnectName)
{
    CDbBaseOper *pBase = nullptr;
    if(enDBTYPE_MYSQL == nDbType)
    {
        pBase = new CDbMysqlOper(sConnectInfo, sConnectName);
    }
    if(enDBTYPE_OPENGAUSS == nDbType)
    {
        pBase = new CDbMysqlOper(sConnectInfo, sConnectName);
    }
    if(enDBTYPE_ORACLE == nDbType)
    {
        pBase = new CDbOracleOper(sConnectInfo, sConnectName);
    }
    if(enDBTYPE_ACCESS == nDbType)
    {
        pBase = new CDbAccessOper(sConnectInfo, sConnectName);
    }
    if(enDBTYPE_SQLSERVER == nDbType)
    {
        pBase = new CDbSqlServerOper(sConnectInfo, sConnectName);
    }
    if(enDBTYPE_SQLITE == nDbType)
    {
        pBase = new CDbSqliteOper(sConnectInfo, sConnectName);
    }
    if(enDBTYPE_DAMENG == nDbType)
    {
        pBase = new CDbDMOper(sConnectInfo, sConnectName);
    }
    return pBase;
}

CDbBaseOper *CDbBaseOper::createCDbSqlOper(const CDataBaseConfig &cDbCfg)
{
    CDbBaseOper *pBase = nullptr;
    if(MYSQL_DRIVER_NAME == cDbCfg.sDBType)
        pBase = new CDbMysqlOper(cDbCfg);
    if(OPENGAUSS_DRIVER_NAME == cDbCfg.sDBType)
        pBase = new CDbOpengaussOper(cDbCfg);
    if(ORACLE_DRIVER_NAME == cDbCfg.sDBType)
        pBase = new CDbOracleOper(cDbCfg);
    if(ACCESS_DRIVER_NAME == cDbCfg.sDBType)
        pBase = new CDbAccessOper(cDbCfg);
    if(SQLSERVER_DRIVER_NAME == cDbCfg.sDBType)
        pBase = new CDbSqlServerOper(cDbCfg);
    if(SQLITE_DRIVER_NAME == cDbCfg.sDBType)
        pBase = new CDbSqliteOper(cDbCfg);
    if(ODBC_DRIVER_NAME == cDbCfg.sDBType)
        pBase = new CDbODBCOper(cDbCfg);
    if(DAMENG_DRIVER_NAME == cDbCfg.sDBType)
        pBase = new CDbDMOper(cDbCfg);
    return pBase;
}

bool CDbBaseOper::open()
{
    bool bRet = false;
    m_db.setHostName(m_dbCfg.sIP);
    m_db.setDatabaseName(m_dbCfg.sName);
    m_db.setUserName(m_dbCfg.sUserName);
    m_db.setPassword(m_dbCfg.sPassWord);
    m_db.setPort(m_dbCfg.nPort);
    m_db.setConnectOptions("MYSQL_OPT_CONNECT_TIMEOUT=2;MYSQL_OPT_READ_TIMEOUT=2");
    if (m_db.open())
    {
        bRet = true;
    }
    return bRet;
}

bool CDbBaseOper::isOpen()
{
    QString sSql = "SELECT 1;";
    QSqlQuery query(m_db);
    bool bReturn = query.exec(sSql);
    return bReturn;
}

void CDbBaseOper::close()
{
    m_db.close();
}

void CDbBaseOper::initTableInfo(CDbTableInfoMgr *pMgr)
{
#if 0
    //测试用
    if(nullptr == pMgr) return;
    QString sSqlStr = "";
    sSqlStr = "select *from " + CDbBaseOper::getTableName(pMgr) + " limit 0";
    QSqlQuery query(m_db);
    query.prepare(sSqlStr);
    if(false == query.exec())
    {
        QString err = query.lastError().text();
        writeLog(MODULE_TYPE_DATABASE, DB_A2T("【GetRecordInfo】初始化表结构失败, SQL:%1").arg(sSqlStr), LOG_FILE);
        writeLog(MODULE_TYPE_DATABASE, DB_A2T("【GetRecordInfo】初始化表结构失败，错误码:%1").arg(err));
        pMgr->m_bSqlOperIsOk = false;
    }
    else
    {
        pMgr->m_mapFieldValue.clear();
        QSqlRecord record = query.record();
        for(int i=0; i<record.count(); ++i)
        {
            QString sField = record.fieldName(i);
            QVariant var = record.value(i);
            pMgr->m_mapFieldValue.insert(sField, var);
        }
        pMgr->m_bSqlOperIsOk = true;
    }
#endif
#if 1
    if(nullptr == pMgr) return;
    QString sSqlStr = "";
    sSqlStr = "select *from " + getTableName(pMgr) + " limit 0";
    QSqlQuery query(m_db);
    query.prepare(sSqlStr);
    if(false == query.exec())
    {
        QString err = query.lastError().text();
        writeLog(DB_A2T("【GetRecordInfo】初始化表结构失败, SQL:%1").arg(sSqlStr),
                 CLogBase::enLevelError, def_FL);
        writeLog(DB_A2T("【GetRecordInfo】初始化表结构失败，错误码:%1").arg(err),
                 CLogBase::enLevelError, def_FL);
        pMgr->m_bSqlOperIsOk = false;
    }
    else
    {
        pMgr->m_mapFieldValue.clear();
        QSqlRecord record = query.record();
        for(int i=0; i<record.count(); ++i)
        {
            QString sField = record.fieldName(i);
            QVariant var = record.value(i);
            pMgr->m_mapFieldValue.insert(sField, var);
        }
        pMgr->m_bSqlOperIsOk = true;
    }
#endif
}

void CDbBaseOper::handleSql(CDbTableDataInfo *pInfo)
{
    CDbTableInfoMgr *pMgr = getTableInfoMgr(pInfo);
    if(nullptr == pMgr) return;
    //判断库表是否已初始化
    if(false == pMgr->m_bInitRecord)
    {
        initTableInfo(pMgr);
        if(pMgr->m_bSqlOperIsOk) pMgr->m_bInitRecord = true;
    }
    switch(pMgr->m_nWorkType)
    {
    case enSQLCREATE:
        handleCreateSql(pMgr);
        break;
    case enSQLINSERT:
        handleInsertSql(pMgr);
        break;
    case enSQLDELETE:
        handleDeleteSql(pMgr);
        break;
    case enSQLUPDATE:
        handleUpdateSql(pMgr);
        break;
    case enSQLSELECT:
        handleSelectSql(pMgr);
        break;
    case enSQLINSERTBATCH:
        handleInsertBatchSql(pMgr);
        break;
    case enSQLCUSTOM:
        handleCustomSql(pMgr);
        break;
    case enSQLEXECUTE:
    case enSQLUNKNOW:
    default:
        handleExecuteSql(pMgr);
        break;
    }
}

bool CDbBaseOper::tryLock(int nTime)
{
    if(nullptr == m_pMutex) return false;
    return m_pMutex->tryLock(nTime);
}

void CDbBaseOper::unlock()
{
    if(nullptr == m_pMutex) return;
    m_pMutex->unlock();
}

bool CDbBaseOper::isTableExist(CDbTableInfoMgr *pMgr)
{
    bool bRet = false;
    QString sSql = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE ";
    sSql += "TABLE_SCHEMA = '" + m_dbCfg.sName + "' and ";
    sSql += "TABLE_NAME = '" + pMgr->m_sTableName + "' ";
    QSqlQuery query(m_db);
    if(false == query.exec()) return bRet;
    while(query.next())
    {
        QSqlRecord record = query.record();
        if(record.isEmpty()) continue;
        bRet = record.value(0).toInt() ? true : false;
    }
    return bRet;
}

QString CDbBaseOper::getTableName(CDbTableInfoMgr *pMgr)
{
    return pMgr->m_sTableName;
}

QString CDbBaseOper::getFieldName(const QString &sSrc)
{
    return sSrc;
}

QString CDbBaseOper::getFieldName(const QString &sSrc, CDbTableInfoMgr *pMgr)
{
    QString sDest = analysisFieldName(sSrc);
    foreach (QString str, pMgr->m_mapFieldValue.keys())
    {
        if(0 != str.compare(sSrc, Qt::CaseInsensitive)) continue;
        sDest = str;
    }
    QString sTemp = sSrc;
    sDest = sTemp.replace(analysisFieldName(sSrc), sDest);
    return sDest;
}

QString CDbBaseOper::analysisAppendSql(CDbTableInfoMgr *pMgr)
{
    return pMgr->m_sSql;
}

void CDbBaseOper::handleCreateSql(CDbTableInfoMgr *pMgr)
{
    //如果数据库中没有这张表 就新建  有就返回true
    if(isTableExist(pMgr))
    {
        pMgr->m_bSqlOperIsOk = true;
        return;
    }
    QString sSqlStr("");
    sSqlStr = pMgr->m_sSql;
    sSqlStr = sSqlStr.replace(pMgr->m_sTableName, getTableName(pMgr));
    QSqlQuery query(m_db);
    query.prepare(sSqlStr);

    pMgr->m_bSqlOperIsOk = true;
    pMgr->m_listErr.append(sSqlStr);
    if (false == query.exec())
    {
        pMgr->m_bSqlOperIsOk = false;
        QString err = query.lastError().text();
        pMgr->m_listErr.append(err);
    }
}

void CDbBaseOper::handleInsertSql(CDbTableInfoMgr *pMgr)
{
    QString sSqlStr("");
    sSqlStr = "insert into " + getTableName(pMgr) + " (";
    //插入字段
    int nSize = pMgr->m_vecResultFieldNameVar.size();
    for (int i = 0; i < nSize; i++)
    {
        sSqlStr += getFieldName(pMgr->m_vecResultFieldNameVar[i].toString());
        if (i != nSize - 1)
            sSqlStr += ",";
    }
    sSqlStr += ") values (";
    //插入值
    for (int i = 0; i < nSize; i++)
    {
        if (i == (nSize - 1))
            sSqlStr += ("?)");
        else
            sSqlStr += ("?,");
    }
    //追加Sql
    sSqlStr += analysisAppendSql(pMgr);
    QSqlQuery query(m_db);
    query.prepare(sSqlStr);
    //字段值类型转换
    for (int i = 0; i < pMgr->m_vecResultFieldValueVar.size()
         && i<pMgr->m_vecResultFieldNameVar.size(); i++)
    {
        QVariant myVar, tarVar;
        myVar = pMgr->m_vecResultFieldValueVar[i];
        tarVar = pMgr->m_mapFieldValue.value(analysisFieldName(pMgr->m_vecResultFieldNameVar[i].toString()));
        typeChange(myVar, tarVar);
        query.bindValue(i, tarVar);
    }
    pMgr->m_bSqlOperIsOk = true;
    pMgr->m_listErr.append(sSqlStr);
    if(false == query.exec())
    {
        pMgr->m_bSqlOperIsOk = false;
        QString err = query.lastError().text();
        writeLog(DB_A2T("【SetInesetStr】执行插入语句失败，SQL:%1").arg(sSqlStr),
                 CLogBase::enLevelError, def_FL);
        writeLog(DB_A2T("【SetInesetStr】执行插入语句失败，错误码:%1").arg(err),
                 CLogBase::enLevelError, def_FL);
        pMgr->m_listErr.append(err);
    }
}

void CDbBaseOper::handleDeleteSql(CDbTableInfoMgr *pMgr)
{
    QString sSqlStr("");
    sSqlStr = "delete from " + getTableName(pMgr);
    //删除条件
    int nSize = pMgr->m_vecFilterFieldName.size();
    if(nSize > 0) sSqlStr += " where ";
    for (int i = 0; i < nSize; i++)
    {
        QString strSrc = pMgr->m_vecFilterFieldName[i];
        //新增条件间符号
        if(pMgr->m_mapSymbol.contains(i))
        {
            sSqlStr += pMgr->m_mapSymbol.value(i) + " ";
        }
        sSqlStr += (getFieldName(strSrc) + "?");
        if (i != nSize - 1)
            sSqlStr += " ";
    }
    //最后的条件间符号
    if(pMgr->m_mapSymbol.contains(nSize))
    {
        sSqlStr += pMgr->m_mapSymbol.value(nSize) + " ";
    }
    //追加Sql
    sSqlStr += analysisAppendSql(pMgr);
    QSqlQuery query(m_db);
    query.prepare(sSqlStr);
    //字段值类型转换
    for (int i = 0; i < pMgr->m_vecFilterFieldValue.size()
         && i<pMgr->m_vecFilterFieldName.size(); i++)
    {
        QVariant myVar, tarVar;
        myVar = pMgr->m_vecFilterFieldValue[i];
        tarVar = pMgr->m_mapFieldValue.value(analysisFieldName(pMgr->m_vecFilterFieldName[i]));
        typeChange(myVar, tarVar);
        query.bindValue(i, tarVar);
    }
    pMgr->m_bSqlOperIsOk = true;
    pMgr->m_listErr.append(sSqlStr);
    if(false == query.exec())
    {
        pMgr->m_bSqlOperIsOk = false;
        QString err = query.lastError().text();
        pMgr->m_listErr.append(err);
    }
}

void CDbBaseOper::handleUpdateSql(CDbTableInfoMgr *pMgr)
{
    QString sSqlStr("");
    sSqlStr = "update " + getTableName(pMgr) + " set ";
    //更新字段
    for (int i = 0; i < pMgr->m_vecResultFieldNameVar.size(); i++)
    {
        sSqlStr += (getFieldName(pMgr->m_vecResultFieldNameVar[i].toString()) + "=? ");
        if (i != pMgr->m_vecResultFieldNameVar.size() - 1)
            sSqlStr += ",";
    }
    sSqlStr += " where ";
    //更新条件
    int nSize = pMgr->m_vecFilterFieldName.size();
    for (int i = 0; i < nSize; i++)
    {
        QString strSrc = pMgr->m_vecFilterFieldName[i];
        //新增条件间符号
        if(pMgr->m_mapSymbol.contains(i))
        {
            sSqlStr += pMgr->m_mapSymbol.value(i) + " ";
        }
        sSqlStr += (getFieldName(strSrc) + "?");
        if (i != nSize - 1)
            sSqlStr += " ";
    }
    //最后的条件间符号
    if(pMgr->m_mapSymbol.contains(nSize))
    {
        sSqlStr += pMgr->m_mapSymbol.value(nSize) + " ";
    }
    //追加Sql
    sSqlStr += analysisAppendSql(pMgr);
    QSqlQuery query(m_db);
    query.prepare(sSqlStr);
    //更新数据类型转换
    for (int i = 0; i < pMgr->m_vecResultFieldValueVar.size() &&
         i<pMgr->m_vecResultFieldNameVar.size(); i++)
    {
        QVariant myVar, tarVar;
        myVar = pMgr->m_vecResultFieldValueVar[i];
        tarVar = pMgr->m_mapFieldValue.value(analysisFieldName(pMgr->m_vecResultFieldNameVar[i].toString()));
        typeChange(myVar, tarVar);
        query.bindValue(i, tarVar);
    }
    //字段值类型转换
    for (int i = pMgr->m_vecResultFieldValueVar.size();
         i < (pMgr->m_vecResultFieldValueVar.size() + pMgr->m_vecFilterFieldValue.size())
         && i<(pMgr->m_vecResultFieldNameVar.size() + pMgr->m_vecFilterFieldName.size()); i++)
    {
        QVariant myVar, tarVar;
        myVar = pMgr->m_vecFilterFieldValue[i - pMgr->m_vecResultFieldValueVar.size()];
        int nIndex = i - pMgr->m_vecResultFieldNameVar.size();
        tarVar = pMgr->m_mapFieldValue.value(analysisFieldName(pMgr->m_vecFilterFieldName[nIndex]));
        typeChange(myVar, tarVar);
        query.bindValue(i, tarVar);
    }
    pMgr->m_bSqlOperIsOk = true;
    pMgr->m_listErr.append(sSqlStr);
    if(false == query.exec())
    {
        pMgr->m_bSqlOperIsOk = false;
        QString err = query.lastError().text();
        writeLog(DB_A2T("【SetUpdateStr】执行更新语句失败，SQL:%1").arg(sSqlStr),
                 CLogBase::enLevelError, def_FL);
        writeLog(DB_A2T("【SetUpdateStr】执行更新语句失败，错误码:%1").arg(err),
                 CLogBase::enLevelError, def_FL);
        pMgr->m_listErr.append(err);
    }
}

void CDbBaseOper::handleSelectSql(CDbTableInfoMgr *pMgr)
{
    QString sSqlStr("");
    sSqlStr = "select * from " + getTableName(pMgr);
    //查询条件
    int nSize = pMgr->m_vecFilterFieldName.size();
    if(nSize > 0) sSqlStr += " where ";
    for (int i = 0; i < nSize; i++)
    {
        QString strSrc = pMgr->m_vecFilterFieldName[i];
        //新增条件间符号
        if(pMgr->m_mapSymbol.contains(i))
        {
            sSqlStr += pMgr->m_mapSymbol.value(i) + " ";
        }
        sSqlStr += (getFieldName(strSrc) + "?");
        if (i != nSize - 1)
            sSqlStr += " ";
    }
    //最后的条件间符号
    if(pMgr->m_mapSymbol.contains(nSize))
    {
        sSqlStr += pMgr->m_mapSymbol.value(nSize) + " ";
    }
    //排序
    sSqlStr += " ";  //用于如果没有排序情况下被删除的最后一个字符
    if(false == pMgr->m_vecOrderName.isEmpty()) sSqlStr += " order by ";
    for(int i=0; i<pMgr->m_vecOrderName.size() &&
        i<pMgr->m_vecOrderValue.size(); ++i)
    {
        sSqlStr += getFieldName(pMgr->m_vecOrderName.at(i)) + " ";
        sSqlStr += pMgr->m_vecOrderValue.at(i) + " ,";
    }
    sSqlStr.chop(1);
    //追加Sql
    sSqlStr += analysisAppendSql(pMgr);
    //查询数量限制
    sSqlStr += " ";
    if(-1 != pMgr->m_nLimit)
    {
        sSqlStr += QString("limit %1").arg(pMgr->m_nLimit);
    }
    QSqlQuery query(m_db);
    query.prepare(sSqlStr);
    //字段值类型转换
    for (int i = 0; i < pMgr->m_vecFilterFieldValue.size() &&
         i<pMgr->m_vecFilterFieldName.size(); i++)
    {
        QVariant myVar, tarVar;
        myVar = pMgr->m_vecFilterFieldValue[i];
        tarVar = pMgr->m_mapFieldValue.value(analysisFieldName(pMgr->m_vecFilterFieldName[i]));
        typeChange(myVar, tarVar);
        query.bindValue(i, tarVar);
    }
    //执行SQL
    pMgr->m_listErr.append(sSqlStr);
    if (false == query.exec())
    {
        pMgr->m_bSqlOperIsOk = false;
        QString err = query.lastError().text();
        writeLog(DB_A2T("【SetSelectStr】执行查询语句失败，SQL:%1").arg(sSqlStr),
                 CLogBase::enLevelError, def_FL);
        writeLog(DB_A2T("【SetSelectStr】执行查询语句失败，错误码:%1").arg(err),
                 CLogBase::enLevelError, def_FL);
        pMgr->m_listErr.append(err);
        return;
    }
    pMgr->m_bSqlOperIsOk = true;
    while (query.next())                   //查询到了遍历 一条一条移动
    {
        pMgr->m_vecReRecord.push_back(query.record());
    }
}

void CDbBaseOper::handleInsertBatchSql(CDbTableInfoMgr *pMgr)
{
    QString sSqlStr("");
    sSqlStr = "insert into " + getTableName(pMgr) + " (";
    //插入字段
    for (int i = 0; i < pMgr->m_vecResultFieldNameVar.size(); i++)
    {
        sSqlStr += getFieldName(pMgr->m_vecResultFieldNameVar[i].toString());
        if (i != pMgr->m_vecResultFieldNameVar.size() - 1)
            sSqlStr += ",";
    }
    sSqlStr += ") values ";
    //字段值
    for (int i = 0; i < pMgr->m_vecBatchData.size(); i++)
    {
        sSqlStr += "(";
        for (int j = 0; j< pMgr->m_vecBatchData[i].size(); j++)
        {
            if (j == (pMgr->m_vecBatchData[i].size() - 1))
            {
                if (i != pMgr->m_vecBatchData.size() - 1)
                    sSqlStr += ("?),");
                else
                    sSqlStr += ("?)");
            }
            else
            {
                sSqlStr += ("?,");
            }
        }
    }
    //追加Sql
    sSqlStr += analysisAppendSql(pMgr);
    QSqlQuery query(m_db);
    query.prepare(sSqlStr);
    int nIndex = 0;
    //字段值类型转换
    for (int i = 0; i < pMgr->m_vecBatchData.size(); i++)
    {
        for (int j = 0; j < pMgr->m_vecBatchData[i].size()
             && j<pMgr->m_vecResultFieldNameVar.size(); j++, nIndex++)
        {
            QVariant myVar, tarVar;
            myVar = pMgr->m_vecBatchData[i][j];
            tarVar = pMgr->m_mapFieldValue.value(analysisFieldName(pMgr->m_vecResultFieldNameVar[j].toString()));
            typeChange(myVar, tarVar);
            query.bindValue(nIndex, tarVar);
        }
    }
    pMgr->m_bSqlOperIsOk = true;
    pMgr->m_listErr.append(sSqlStr);
    if(false == query.exec())
    {
        pMgr->m_bSqlOperIsOk = false;
        QString err = query.lastError().text();
        writeLog(DB_A2T("【SetInesetStr】执行插入语句失败，SQL:%1").arg(sSqlStr),
                 CLogBase::enLevelError, def_FL);
        writeLog(DB_A2T("【SetInesetStr】执行插入语句失败，错误码:%1").arg(err),
                 CLogBase::enLevelError, def_FL);
        pMgr->m_listErr.append(err);
    }
}

void CDbBaseOper::handleCustomSql(CDbTableInfoMgr *pMgr)
{
    //非绑定调用，直接执行sql
    if(pMgr->m_vecResultFieldNameVar.isEmpty())
        handleExecuteSql(pMgr);
    else
        handleBindValueSql(pMgr);
}

void CDbBaseOper::handleExecuteSql(CDbTableInfoMgr *pMgr)
{
    QSqlQuery query(m_db);
    pMgr->m_bSqlOperIsOk = true;
    pMgr->m_listErr.append(pMgr->m_sSql);
    if(false == query.exec(pMgr->m_sSql))
    {
        pMgr->m_bSqlOperIsOk = false;
        pMgr->m_listErr.append(query.lastError().text());
        return;
    }
    //判断语句类型
    analysisCustomSqlType(pMgr);
    if(enSQLSELECT != pMgr->m_nSqlType) return;
    //查询语句特殊处理
    while (query.next())                   //查询到了遍历 一条一条移动
    {
        pMgr->m_vecReRecord.push_back(query.record());
    }
}

void CDbBaseOper::handleBindValueSql(CDbTableInfoMgr *pMgr)
{
    QSqlQuery query(m_db);
    pMgr->m_bSqlOperIsOk = true;
    pMgr->m_listErr.append(pMgr->m_sSql);
    query.prepare(pMgr->m_sSql);
    int index = 0;
    //类型转换，数据绑定
    for(int i=0; i<pMgr->m_vecResultFieldNameVar.size() &&
        i<pMgr->m_vecResultFieldValueVar.size(); ++i)
    {
        QString sField = pMgr->m_vecResultFieldNameVar.at(i).toString();
        QVariant myVar, tarVar;
        myVar = pMgr->m_vecResultFieldValueVar.at(i);
        //不存在的字段
//        writeLog(MODULE_TYPE_DATABASE, QString(DB_A2T("【数据库操作】绑定数据：%1, %2")).arg(sField).arg(myVar.toString()));
        if(false == pMgr->m_mapFieldValue.contains(sField)) continue;
        tarVar = pMgr->m_mapFieldValue.value(analysisFieldName(sField));
        typeChange(myVar, tarVar);
        query.bindValue(index++, tarVar);
    }
    //执行sql
    if(false == query.exec())
    {
        pMgr->m_bSqlOperIsOk = false;
        pMgr->m_listErr.append(query.lastError().text());
        return;
    }
    //判断语句类型
    analysisCustomSqlType(pMgr);
    if(enSQLSELECT != pMgr->m_nSqlType) return;
    //查询语句特殊处理
    while (query.next())                   //查询到了遍历 一条一条移动
    {
        pMgr->m_vecReRecord.push_back(query.record());
    }
}

void CDbBaseOper::typeChange(QVariant src, QVariant &dest)
{
    int type = dest.type();
    switch (type)
    {
    case QVariant::Bool:
        dest = src.toBool();
        break;
    case QVariant::Int:
        dest = src.toInt();
        break;
    case QVariant::UInt:
        dest = src.toUInt();
        break;
    case QVariant::LongLong:
        dest = src.toLongLong();
        break;
    case QVariant::ULongLong:
        dest = src.toULongLong();
        break;
    case QVariant::Double:
        dest = src.toDouble();
        break;
    case QVariant::Char:
        dest = src.toChar();
        break;
    case QVariant::Map:
        dest = src.toMap();
        break;
    case QVariant::List:
        dest = src.toList();
        break;
    case QVariant::String:
        if (src.type() == QVariant::Double)
        {
            dest = QString::number(src.toDouble());
        }
        else if (src.type() == QVariant::Date
                 || src.type() == QVariant::Time
                 || src.type() == QVariant::DateTime)
        {
            dest = src.toDateTime().toString("yyyy-MM-dd hh:mm:ss");
        }
        else
        {
            dest = src.toString();
        }
        break;
    case QVariant::StringList:
        dest = src.toStringList();
        break;
    case QVariant::ByteArray:
        dest = src.toString();
        break;
    case QVariant::BitArray:
        dest = src.toByteArray();
        break;
    case QVariant::Date:
        dest = src.toDate();
        break;
    case QVariant::Time:
        dest = src.toTime();
        break;
    case QVariant::DateTime:
        dest = src.toDateTime();
        break;
    case QVariant::Url:
        dest = src.toString();
        break;
    default:
        dest = src.toString();
        break;
    }
}

QString CDbBaseOper::analysisFieldName(const QString &sSrc)
{
    QString sSplit = "=";
    if(sSrc.contains(">")) sSplit = ">";
    if(sSrc.contains("<")) sSplit = "<";
    if(sSrc.contains("!=")) sSplit = "!=";
    if(sSrc.contains(">=")) sSplit = ">=";
    if(sSrc.contains("<=")) sSplit = "<=";
    QStringList listStr = sSrc.split(sSplit);
    listStr.removeAll("");
    listStr.removeAll(" ");
    if(sSrc.indexOf(sSplit) < sSrc.indexOf(listStr.last())) listStr.removeLast();
    if(listStr.isEmpty()) return sSrc;
    QString strRet = listStr.last();
    listStr = strRet.split(" ");
    listStr.removeAll("");
    if (listStr.isEmpty()) return "";
    QString reStr = listStr.last();
    reStr.remove("(");
    reStr.remove(")");
    return reStr;
}

void CDbBaseOper::analysisCustomSqlType(CDbTableInfoMgr *pMgr)
{
    if(pMgr->m_sSql.isEmpty()) return;
    //转为大写，方便识别
    QString sSql = pMgr->m_sSql.toUpper();
    QStringList listSql = sSql.split(" ");
    listSql.removeAll("");
    if("INSERT" == listSql.at(0))
    {
        pMgr->m_nSqlType = enSQLINSERT;
    }
    else if("DELETE" == listSql.at(0))
    {
        pMgr->m_nSqlType = enSQLDELETE;
    }
    else if("UPDATE" == listSql.at(0))
    {
        pMgr->m_nSqlType = enSQLUPDATE;
    }
    else if("SELECT" == listSql.at(0))
    {
        pMgr->m_nSqlType = enSQLSELECT;
    }
    else if("CREATE" == listSql.at(0))
    {
        pMgr->m_nSqlType = enSQLCREATE;
    }
}

void CDbBaseOper::writeLog(const QString &sLogText, const int &nType, const QString &sFl)
{
    if(nullptr == m_pLog)
    {
        qDebug() << QObject::tr("[Database Module][%1:%2] : %3")
                    .arg(sFl).arg(nType).arg(sLogText);
        return;
    }
    m_pLog->writeLog(QObject::tr("Database Module"), sLogText, nType, sFl, 0);
}
